package com.daoliuhe.scaffold.web.controller.admin;

import com.daoliuhe.scaffold.model.User;
import com.daoliuhe.scaffold.service.SessionService;
import com.daoliuhe.scaffold.core.RedisSessionDAO;
import com.daoliuhe.scaffold.tools.Constants;
import com.daoliuhe.scaffold.tools.DateUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.io.UnsupportedEncodingException;
import java.util.*;

@Controller
@RequestMapping("/sessions")
public class SessionController {

    /**
     * 日志
     */
    private static final Logger logger = LoggerFactory.getLogger(SessionController.class);

    @Autowired
    SessionService sessionService;
    @Autowired
    RedisSessionDAO sessionDAO;

    @RequestMapping("/list")
    public ModelAndView list(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int rows,
            String loginId,
            String userName,
            String host,
            String deptName
    ) throws UnsupportedEncodingException {
        logger.info("list, page:{},row:{}", page, rows);
        ModelAndView mav = new ModelAndView("admin/sessions/list");
        List<Map<String, Object>> retList = new ArrayList<Map<String, Object>>();
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        for (Session session : sessions) {
            Map<String, Object> map = new HashMap<String, Object>();
            User userInfo = (User) session.getAttribute(Constants.USERINFO);
            if (userInfo != null) {
                map.put("id", session.getId());
                String userIp = (String) session.getAttribute(Constants.USER_IP);
                if (StringUtils.isEmpty(userIp)) {
                    userIp = session.getHost();
                }
                map.put("host", userIp);
                map.put("lastAccessTime", null == session.getLastAccessTime() ? "" : DateUtil.format(session.getLastAccessTime()));
                map.put("lat", session.getLastAccessTime());
                map.put("startTime", null == session.getStartTimestamp() ? "" : DateUtil.format(session.getStartTimestamp()));
                map.put("userInfo", null == userInfo ? "" : userInfo.getShowName());
                map.put("deptName", null == userInfo ? "" : userInfo.getDeptName());
                Object forceLogout = session.getAttribute(Constants.SESSION_FORCE_LOGOUT_KEY);
                map.put("forceLogout", null == forceLogout ? "N" : "Y");
                boolean queryRet = true;
                //账号
                if (StringUtils.hasText(loginId)) {
                    String userLoginId = userInfo.getLoginId();
                    if (StringUtils.hasText(userLoginId) && userLoginId.contains(loginId)) {
                        queryRet = true;
                    } else {
                        queryRet = false;
                    }
                }
                //姓名
                if (queryRet && StringUtils.hasText(userName)) {
                    String name = userInfo.getUserName();
                    if (StringUtils.hasText(name) && name.contains(userName)) {
                        queryRet = true;
                    } else {
                        queryRet = false;
                    }
                }
                //主机地址
                if (queryRet && StringUtils.hasText(host)) {
                    if (StringUtils.hasText(userIp) && userIp.contains(host)) {
                        queryRet = true;
                    } else {
                        queryRet = false;
                    }
                }
                //部门名称
                if (queryRet && StringUtils.hasText(deptName)) {
                    String dptName= userInfo.getDeptName();
                    if (StringUtils.hasText(dptName) && dptName.contains(deptName)) {
                        queryRet = true;
                    } else {
                        queryRet = false;
                    }
                }
                if (queryRet) {
                    retList.add(map);
                }
            }
        }
        // 根据最后访问时间倒序排列
        Collections.sort(retList, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> m1, Map<String, Object> m2) {
                return ((Date) m2.get("lat")).compareTo((Date) m1.get("lat"));
            }
        });

        mav.addObject("page", page);
        mav.addObject("rows", rows);
        mav.addObject("loginId", loginId);
        mav.addObject("userName", userName);
        mav.addObject("host", host);
        mav.addObject("deptName", deptName);
        int size = retList.size();
        mav.addObject("total", size);
        mav.addObject("list", retList.subList((page - 1) * rows, page * rows > size ? size : page * rows));
        return mav;
    }

    @RequestMapping("/data")
    @ResponseBody
    public Object data() {
        logger.info("data");
        List<Map<String, Object>> retList = new ArrayList<Map<String, Object>>();
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        for (Session session : sessions) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", session.getId());
            map.put("host", session.getHost());
            map.put("lastAccessTime", session.getLastAccessTime());
            map.put("startTime", session.getStartTimestamp());
            User userInfo = (User) session.getAttribute(Constants.USERINFO);
            map.put("userInfo", null == userInfo ? "" : userInfo.getShowName());
            map.put("deptName", null == userInfo ? "" : userInfo.getDeptName());
            Object forceLogout = session.getAttribute(Constants.SESSION_FORCE_LOGOUT_KEY);
            map.put("forceLogout", null == forceLogout ? "N" : "Y");
            retList.add(map);
        }
        return retList;
    }

    @RequestMapping("/forceLogout")
    public String forceLogout(String sessionIds) {
        logger.info("forceLogout, sessionIds:{}", sessionIds);
        try {
            List<String> list = Arrays.asList(sessionIds.split(","));
            for (String sessionId : list) {
                Session session = sessionDAO.readSession(sessionId);
                if (session != null) {
                    session.setAttribute(Constants.SESSION_FORCE_LOGOUT_KEY, Boolean.TRUE);
                    logger.debug("LOGOUT_KEY:{}", session.getAttribute(Constants.SESSION_FORCE_LOGOUT_KEY));
                    sessionDAO.update(session);
                }
            }
        } catch (Exception e) {
            logger.error("forceLogout, sessionIds:{}, e:{}", sessionIds, e.getMessage());
        }

        return "redirect:/sessions/list";
    }

    @RequestMapping("/sendEmail")
    public String sendEmail(String title, String content) {
        User sendUser = (User) SecurityUtils.getSubject().getSession().getAttribute(Constants.USERINFO);
        logger.info("sendEmail, sendUser:{}, title:{}, content:{}", sendUser, title, content);
        sessionService.sendEmails(title, content);
        return "redirect:/sessions/list";
    }
}
